Visualization¶

In [1]:
# Activate intractive functionality of matplotlib
%matplotlib ipympl
# Activate auto reload 
%load_ext autoreload
%autoreload 2
%reload_ext autoreload
# import libraries
import os
import pandas as pd
from ipywidgets import fixed, interact_manual, widgets
from ipywidgets import VBox
from IPython.display import clear_output
from IPython.display import display
from ipywidgets import Output
import matplotlib.colors as mcolors
import warnings
# Ignore all warnings
warnings.filterwarnings("ignore")

# Local module and scripts
from pyccapt.calibration.calibration_tools import share_variables, ion_selection
from pyccapt.calibration.calibration_tools import widgets as wd
from pyccapt.calibration.data_tools import data_tools, dataset_path_qt
from pyccapt.calibration.reconstructions import reconstruction
from pyccapt.calibration.calibration_tools import mc_plot

By clicking on the button below, you can select the dataset file you want to use. The dataset file can be in various formats, including HDF5, EPOS, POS, ATO, and CSV.

In [2]:
button = widgets.Button(
    description='load dataset',
)
@button.on_click
def open_file_on_click(b):
    """
    Event handler for button click event.
    Prompts the user to select a dataset file and stores the selected file path in the global variable dataset_path.
    """
    global dataset_path
    dataset_path = dataset_path_qt.gui_fname().decode('ASCII')
button
Out[2]:
If you ranged the dataset, you can select the range file by clicking on the button below. The range file can be created with "ion selection and ranging" workflow. If you do not have a range file, you can skip this step.
In [3]:
button_r = widgets.Button(
    description='load range dataset',
)
@button_r.on_click
def open_file_on_click_r(b):
    """
    Event handler for button click event.
    Prompts the user to select a range file and stores the selected file path in the global variable range_path.
    """
    global range_path
    range_path = dataset_path_qt.gui_fname().decode('ASCII')
button_r
Out[3]:
From the dropdown lists below, you can select the instrument specifications of the dataset. The TDC model and flight path distance are required for the reconstruction.
In [4]:
tdc, pulse_mode, flightPathLength, t0_d, max_mc, det_diam = wd.dataset_instrument_specification_selection()
display(tdc, flightPathLength)
In [5]:
# exctract needed data from Pandas data frame as an numpy array
# create an instance of the Variables opject
variables = share_variables.Variables()
variables.pulse_mode = pulse_mode
dataset_main_path = os.path.dirname(dataset_path)
dataset_main_path = os.path.dirname(dataset_main_path)
dataset_name_with_extension = os.path.basename(dataset_path)
variables.dataset_name = os.path.splitext(dataset_name_with_extension)[0]
variables.result_data_path = dataset_main_path 
variables.result_data_name = variables.dataset_name
variables.result_path = dataset_main_path + '/visualization/'

if not os.path.isdir(variables.result_path):
    os.makedirs(variables.result_path, mode=0o777, exist_ok=True)
    
# Create data farame out of hdf5 file dataset
data = data_tools.load_data(dataset_path, tdc.value, mode='processed')
# extract data from the path and create the Variable object
data_tools.extract_data(data, variables, flightPathLength.value, max_mc.value)
The maximum time of flight: 5010
In [6]:
data
Out[6]:
x (nm) y (nm) z (nm) mc_c (Da) mc (Da) high_voltage (V) pulse start_counter t_c (ns) t (ns) x_det (cm) y_det (cm) pulse_pi ion_pp
0 21.387474 4.793744 3.742590 27.362214 28.993453 5019.959961 1003.992004 7565 572.395831 618.564148 2.651428 0.594286 0 0
1 -0.465509 5.449197 0.226819 27.034338 29.360520 5019.959961 1003.992004 7664 569.176119 606.260925 -0.055510 0.649796 99 2
2 -0.903869 5.094536 0.202985 27.100974 29.441372 5019.959961 1003.992004 7682 569.832045 606.932983 -0.107755 0.607347 18 1
3 18.634826 -3.726965 2.792876 27.100149 28.725689 5019.959961 1003.992004 7690 569.823932 611.520996 2.285714 -0.457143 8 1
4 4.014661 14.361170 1.705268 27.236032 29.512555 5019.959961 1003.992004 7794 571.159024 614.298462 0.486531 1.740408 104 1
... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
10559761 -4.831920 15.283945 57.205555 27.244832 29.759238 6351.169922 1270.234009 19549 571.245368 550.999146 -0.460408 1.456326 105 1
10559762 -14.125940 -1.271678 56.866164 27.414528 29.967560 6351.169922 1270.234009 19664 572.907770 551.705505 -1.342041 -0.120816 31 1
10559763 16.429191 3.148928 57.345214 27.119032 29.029561 6351.169922 1270.234009 19762 570.009661 545.156128 1.567347 0.300408 98 1
10559764 13.831981 -9.107195 57.311214 26.980992 28.815053 6351.169922 1270.234009 19833 568.650437 543.187866 1.319184 -0.868571 71 1
10559765 -4.686109 -28.183125 60.689258 27.017776 28.904500 6351.169922 1270.234009 317 569.012971 554.791626 -0.460408 -2.768980 4294947780 1

10559766 rows × 14 columns

In [7]:
if 'range_path' in locals():
    variables.range_data = data_tools.read_hdf5_through_pandas(range_path)

else:
    variables.range_data = pd.DataFrame({"ion": ['unranged'], "mass": [0], "mc": [0], "mc_low": 0,
                                        "mc_up": 400, "color": '#000000', "element": ['unranged'],
                                        "complex": [0], "isotope": [0], "charge": [0]})

if variables.range_data.empty:
    element_percentage = str([0.01])
else:
    element_percentage = [0.01] * len(variables.range_data['element'].tolist())
    element_percentage = str(element_percentage)
    
display(variables.range_data.style.applymap(ion_selection.display_color, subset=['color']))
  ion mass mc mc_low mc_up color element complex isotope charge
0 ${}^{1}H^{+}$ 1.010000 1.002547 0.786895 1.154829 #b2aa2d ['H'] [1] [1] 1
1 ${}^{27}Al^{2+}$ 13.490000 13.433484 13.291419 14.248047 #e7e0d1 ['Al'] [1] [27] 2
2 ${}^{27}Al^{+}$ 26.980000 26.967166 26.273200 28.983645 #e7e0d1 ['Al'] [1] [27] 1
In [8]:
change_color = widgets.Button(
    description='change color',
)
color_picker = widgets.ColorPicker(description='Select a color:')
row_index = widgets.IntText(value=0, description='index row:')
@change_color.on_click
def change_color_m(b,):
    with out:
        selected_color = mcolors.to_hex(color_picker.value)
        variables.range_data.at[row_index.value, 'color'] = selected_color
        clear_output(True)
        display(variables.range_data.style.applymap(ion_selection.display_color, subset=['color']))
        
# Create a container for the widgets
container = widgets.VBox([color_picker, row_index, change_color])
out = Output()
# Display the widgets
display(container, out)
In [23]:
plot_3d_button = widgets.Button(
    description='plot 3D',
)
plot_heatmap_button = widgets.Button(
    description='plot heatmap',
)
plot_mc_button = widgets.Button(
    description='plot mc',
)
plot_projection_button = widgets.Button(
    description='plot projection',
)

clear_button = widgets.Button(
    description='Clear plots',
)

figname_3d=widgets.Text(value='3d_plot', description='fig name')
selected_area_p3=widgets.Dropdown(options=[('False', False), ('True', True)], description='Selected area')
rotary_fig_save_p3=widgets.Dropdown(options=[('True', True), ('False', False)], description='Rotary save')
element_percentage_p3=widgets.Textarea(value=element_percentage, description='Element percentage')
@plot_3d_button.on_click
def plot_3d(b):
    with out:
        if selected_area_p3.value:
            variables.selected_z1 = variables.selected_y1
            variables.selected_z2 = variables.selected_y2
            variables.selected_y1 = variables.selected_x1
            variables.selected_y2 = variables.selected_x2
            print('Min x (nm):', variables.selected_x1, 'Max x (nm):', variables.selected_x2)
            print('Min y (nm):', variables.selected_y1, 'Max y (nm):', variables.selected_y2)
            print('Min z (nm):', variables.selected_z1, 'Max z (nm):', variables.selected_z2)
        opacity = 1
        reconstruction.reconstruction_plot(variables, element_percentage_p3.value, opacity, rotary_fig_save_p3.value,  figname_3d.value, save=True,
                                           selected_area_specially=selected_area_p3.value, selected_area_temporally=selected_area_p3.value, ions_individually_plots=False)

selected_area_ph=widgets.Dropdown(options=[('False', False), ('True', True)], description='Selected area')
element_percentage_ph=widgets.Textarea(value=element_percentage, description='Element percentage')
figname_heatmap=widgets.Text(value='heatmap', description='fig name')
@plot_heatmap_button.on_click
def plot_heatmap(b, variables=variables):
    with out:
        if selected_area_ph.value:
            variables.selected_z1 = variables.selected_y1
            variables.selected_z2 = variables.selected_y2
            variables.selected_y1 = variables.selected_x1
            variables.selected_y2 = variables.selected_x2
            print('Min x (nm):', variables.selected_x1, 'Max x (nm):', variables.selected_x2)
            print('Min y (nm):', variables.selected_y1, 'Max y (nm):', variables.selected_y2)
            print('Min z (nm):', variables.selected_z1, 'Max z (nm):', variables.selected_z2)

        reconstruction.heatmap(variables, selected_area_ph.value, selected_area_ph.value, element_percentage_ph.value, figure_name='heat_map', figure_sie=(5,5), save=True)

selected_area_pm=widgets.Dropdown(options=[('False', False), ('True', True)], description='Selected area')
peak_find_plot=widgets.Dropdown(options=[('True', True), ('False', False)], description='peak find')
rangging=widgets.Dropdown(options=[('False', False), ('True', True)], description='rangging')
range_file_exist_pm=widgets.Dropdown(options=[('True', True), ('False', False)], description='Range exist')
bin_size_pm = widgets.FloatText(value=0.1, description='Bins size')
lim_mc_pm = widgets.IntText(value=150, description='Limit mc')
prominence=widgets.IntText(value=50, description='peak prominance:')
distance=widgets.IntText(value=50, description='peak distance:')
hist_color_range=widgets.Dropdown(options=[('True', True), ('False', False)], description='hist color')
figname_mc=widgets.Text(value='mc', description='fig name')
@plot_mc_button.on_click
def plot_mc(b,):
    with out:
        if selected_area_pm.value:
            variables.selected_z1 = variables.selected_y1
            variables.selected_z2 = variables.selected_y2
            variables.selected_y1 = variables.selected_x1
            variables.selected_y2 = variables.selected_x2
            print('Min x (nm):', variables.selected_x1, 'Max x (nm):', variables.selected_x2)
            print('Min y (nm):', variables.selected_y1, 'Max y (nm):', variables.selected_y2)
            print('Min z (nm):', variables.selected_z1, 'Max z (nm):', variables.selected_z2)

        mc_plot.hist_plot(variables, bin_size_pm.value, log=True, target='mc_c', mode='normal', prominence=prominence.value, distance=distance.value, percent=50, selector='None', figname=figname_mc.value, lim=lim_mc_pm.value,
                          peaks_find_plot=peak_find_plot.value, peaks_find=True, range_plot=rangging.value, plot_ranged_ions=False, ranging_mode=False, selected_area_specially=selected_area_pm.value,
                          selected_area_temporally=False, save_fig=True, print_info=True, figure_size=(9, 5))
element_percentage_pp=widgets.Textarea(value=element_percentage, description='Element percentage')
selected_area_pp=widgets.Dropdown(options=[('False', False), ('True', True)], description='Selected area')
x_or_y_pp=widgets.Dropdown(options=['x', 'y'], value='x', description='X or Y')
figname_p = widgets.Text(value='projection', description='fig name')
@plot_projection_button.on_click
def plot_projection(b,):
    with out:
        if selected_area_pp.value:
            variables.selected_z1 = variables.selected_y1
            variables.selected_z2 = variables.selected_y2
            variables.selected_y1 = variables.selected_x1
            variables.selected_y2 = variables.selected_x2
            print('Min x (nm):', variables.selected_x1, 'Max x (nm):', variables.selected_x2)
            print('Min y (nm):', variables.selected_y1, 'Max y (nm):', variables.selected_y2)
            print('Min z (nm):', variables.selected_z1, 'Max z (nm):', variables.selected_z2)

        reconstruction.projection(variables, element_percentage_pp.value, selected_area_pp.value, selected_area_pp.value, x_or_y_pp.value, figname_p.value,
                                 figure_size=(5,5), save=True)

@clear_button.on_click
def clear(b,):
    with out:
        clear_output(True)
        print('')


tab1 = VBox(children=[selected_area_pp, x_or_y_pp, element_percentage_pp, figname_p, plot_projection_button, clear_button])
tab2 = VBox(children=[selected_area_p3, rotary_fig_save_p3, element_percentage_p3, figname_3d, plot_3d_button, clear_button])
tab3 = VBox(children=[selected_area_pm, bin_size_pm, prominence, distance, lim_mc_pm, peak_find_plot, rangging, figname_mc, plot_mc_button, clear_button])
tab4 = VBox(children=[selected_area_ph, element_percentage_ph, figname_heatmap, plot_heatmap_button, clear_button])

tab = widgets.Tab(children=[tab1, tab2, tab3, tab4])
tab.set_title(0, 'projection')
tab.set_title(1, '3d plot')
tab.set_title(2, 'mc plot')
tab.set_title(3, 'heatmap plot')

out = Output()
In [24]:
display(VBox(children=[tab]))
display(out)
In [17]:
 
In [ ]: